This invention relates generally to microprocessors and their architecture for executing instructions and, more specifically, to the implementation of AND, OR, TEST commands with equal operands.
Due to its familiarity, the discussion below will use the Intel.TM. X86 architecture when it is necessary to be specific. The book by Intel, Intel Architecture Software Developer's Manual, Volume 2, 1997, gives more details and is hereby incorporated herein by this reference.
As it is usually implemented, a microprocessor contains as part of its architecture a number of registers. These commonly contain a set of general purpose registers to hold data or address quantities, called AX, BX, and so on. An additional set of standard registers is known as the flags register. A collection of commands, the instruction set, controls the operation of the microprocessor.
The flags register consists of a number of small, usually one bit, subregisters, or flags, that control a number of conditional instructions and indicate the status of the processor. The microprocessor frequently needs to assign values to these flags for conditional transfers, such as jump instructions dependent upon the value of a certain flag. An example is the zero flag (ZF) that is set if the outcome of a particular instruction is zero. This flag is then consulted by subsequent operations if it should become important to determine if a particular operand is zero.
Some of the basic members of the instruction set are the logical command OR, the logical command AND, and the related TEST command. An OR command with, say, two registers as operands compares the contents of the two registers and forms the logical OR of the two on a bit by bit basis. It then writes the result back, in this example to the first register:
or ax,bx; AX.rarw.[AX] OR [BX]. PA0 and ax,bx; AX.rarw.[AX] AND [BX], PA0 and ax,ax; AX.rarw.[AX] AND [AX]
(The notation here is that the contents of a register are indicated by placing the register s label in brackets, for example [AX] are the contents of AX. ) Finally, the appropriate flags are given values according to the outcome of the command. Similarly, an AND command, again using the example where the operands are two registers,
will AND the contents of the two registers on a bit by bit basis, write the result back, and then assign the flags accordingly. A TEST command is the same as an AND command, except it does not write the result back.
The use of the AND, OR, and TEST commands with equal operands is a convenient method for adjusting the values in the flags register. To understand why this is useful, consider the following segment of code where MEM is some memory address and ADDR some target instruction:
sub cx,bx ; CX .rarw. [CX] - [BX] mov ax,mem ; moves [MEM] into AX jz addr ; jumps to ADDR if zero flag is set, ZF=1.
The problem with this set of instructions is that neither the move command nor the jump command affect the flags. This jump instruction, JZ, will be carried out based on the status of the zero flag as previously set by the subtraction. If the programmer intends for this jump to be based on the values in the register AX as it stands after the move command has been executed, the flags need to be set or reset appropriately. A way to do this is to use the AND, OR, or TEST command with AX as both of its arguments.
By ANDing the register AX with itself, the contents of AX, [AX], will be compared bit by bit to themselves, written back into AX, and the flags set according to the outcome of the operation. But the result of forming the logical AND of a bit with itself is just to give the same value back for that bit, regardless of whether it is 0 or 1. Thus the result of
will be to leave the value of AX unchanged. The flags register will now be set to reflect the result of the command, but as this was just [AX], the flags now indicate the contents of this register. As the result of the logical OR of something with itself is also just the thing back, and as a TEST instruction is just an AND without the writeback, these two instructions will act in exactly the same way as the AND instruction when their operands are equal.
Going back to the fragment of code above, if the programmer intended for the jump to depend on the contents of AX, it should be written as
 sub cx,bx ; CX .rarw. [CX] - [BX] mov ax,mem ; moves [MEM] into AX and ax,ax ; AX .rarw. [AX] AND [AX] jz addr ; jumps to ADDR if zero flag is set, ZF=1.
Inserting the AND line will leave the value of AX unchanged, but the flags will now reflect AX, not some previous operation. The jump JZ will now depend on whether [AX]=0. Note that either an OR or a TEST instruction could be used instead of the AND, their result being the same when all the operands are equal.
While this shows the utility of the AND/OR/TEST with equal operands, it also gives some indication of the redundancies inherent in its execution. To execute this command, the microprocessor must execute a number of actions. First it must get the contents of the operand, compare these with themselves on a bit by bit basis, and then (except for TEST) write the result back. The result of these steps is that the operand's contents are unchanged. More to the point, it must also note the outcome of the command and adjust a number of flags accordingly. Thus to perform this command and its attendant executions will require several steps, largely redundant, and therefore may use several clock cycles.
The consequences of this are particularly acute in a multiple pipeline microprocessor. Here, several commands are issued in parallel. This often results in some instructions having to wait as they may be dependent upon the outcome of another instruction. Going back to the example, consider again
 mov ax,mem ; moves [MEM] into AX and ax,ax ; AX .rarw. [AX] AND [AX] jz addr ; jumps to ADDR if zero flag is set, ZF=1,
where the jump instruction JZ depends on the outcome of the AND--which itself depends on the MOV instruction--and must wait for it to finish in that instruction's pipeline. Hence, when one instruction is paired with preceding dependent instructions, several pipelines may be stalled for one or more clock cycles.
Since the result of the AND/OR/TEST command with equal operands is known in advance to just be the original operand, regardless of the actual contents, this instruction results in the redundancies listed above. As this instruction is a useful technique, the resultant consumption of time and power can become significant.
It is the primary object of the present invention to reduce these limitations by decreasing the amount of redundancy in executing AND/OR/TEST instructions with equal operands.
It is another object to increase speed and reduce power consumption within a microprocessor.